import base64

from django.core.exceptions import ValidationError
from django.utils import timezone

from app.models import MerchantInfo, MerchantImage, User
from django.db import transaction, models

from app.services.image_service import ImageService
from middleware.util import make_response


class MerchantService:
    @staticmethod
    def register_merchant(user_id, shop_name, location, contact_info, business_hours, introduction=None, images=None):
        """
        商家注册核心逻辑
        :param user_id: 当前用户的 UUID
        :param shop_name: 商家名称
        :param location: 地址
        :param contact_info: 联系方式
        :param business_hours: 营业时间
        :param images: 图片二进制数据列表或已上传的图片 ID 列表
        :return: 注册结果
        """
        try:
            # 1. 获取用户并校验角色
            user = User.objects.get(id=user_id)
            if user.role != 'customer':
                raise ValidationError("只有普通用户可以申请成为商家")

            # 2. 验证商家名称是否已存在
            if MerchantInfo.objects.filter(shop_name=shop_name).exists():
                raise ValidationError("该商家名称已被占用")

            with transaction.atomic():
                # 3. 处理图片上传（如果提供了图片二进制数据）
                image_ids = []
                if images and isinstance(images[0], bytes):  # 如果是二进制数据
                    for image_data, mime_type in images:
                        image_id = ImageService.add_image(image_data, mime_type)
                        image_ids.append(image_id)
                else:  # 如果是已上传的图片 ID
                    image_ids = images or []

                # 4. 创建商家信息
                merchant = MerchantInfo.objects.create(
                    merchant_id=user.id,  # 商家 ID 与用户 ID 一致
                    shop_name=shop_name,
                    location=location,
                    contact_info=contact_info,
                    business_hours=business_hours,
                    register_time=user.created_at,
                    introduction=introduction,
                )

                # 5. 关联图片
                for idx, image_id in enumerate(image_ids):
                    MerchantImage.objects.create(
                        merchant=merchant,
                        image_id=image_id,
                        sort_order=idx
                    )

                # 6. 更新用户角色为商家
                user.role = 'merchant'
                user.save()

            return make_response(
                        code=201,
                        message="商家注册成功",
                        data={
                    "merchant_id": str(merchant.merchant_id),
                    "shop_name": merchant.shop_name
                }
            )

        except User.DoesNotExist:
            raise ValidationError("用户不存在")
        except Exception as e:
            raise ValidationError(f"注册失败：{str(e)}")

    @staticmethod
    def update_merchant_images(user_id, image_list):
        """
        更新商家图片关联关系。
        :param user_id: 商家 ID（UUID）
        :param image_list: 包含 Base64 图片数据的列表，格式为:
            [
                {"data": "base64_string", "mime_type": "image/jpeg"},
                ...
            ]
        :return: 统一格式响应
        """
        try:
            merchant = MerchantInfo.objects.get(merchant_id=user_id)

            with transaction.atomic():
                image_ids = []

                for img_info in image_list:
                    base64_data = img_info.get("data")
                    mime_type = img_info.get("mime_type")

                    if not base64_data or not mime_type:
                        raise ValidationError("缺少图片数据或 MIME 类型")

                    # ✅ Base64 解码为原始二进制数据
                    try:
                        image_binary = base64.b64decode(base64_data)
                    except (TypeError, ValueError) as e:
                        raise ValidationError(f"Base64 解码失败: {e}")

                    # ✅ 上传图片到统一服务（接收二进制）
                    image_id = ImageService.add_image(image_data=image_binary, mime_type=mime_type)
                    image_ids.append(image_id)

                # 🧹 删除旧的图片关联
                MerchantImage.objects.filter(merchant=merchant).delete()

                # ➕ 创建新的图片关联
                for idx, image_id in enumerate(image_ids):
                    MerchantImage.objects.create(
                        merchant=merchant,
                        image_id=image_id,
                        sort_order=idx
                    )

            return make_response(
                code=200,
                message="商家图片更新成功",
                data={
                    "merchant_id": str(merchant.merchant_id),
                    "image_count": len(image_ids)
                }
            )

        except MerchantInfo.DoesNotExist:
            raise ValidationError("商家信息不存在")
        except Exception as e:
            raise ValidationError(f"更新失败：{str(e)}")

    @staticmethod
    def update_merchant_info(user_id, shop_name=None, location=None, business_hours=None, contact_info=None,
                             introduction=None):
        """
        更新商家基本信息
        :param user_id: 当前用户的 UUID（从 JWT 解析）
        :param shop_name: 商家名称（可选）
        :param location: 地址（可选）
        :param business_hours: 营业时间（可选）
        :param contact_info: 联系方式（可选）
        :param introduction: 商家自我介绍（可选）
        :return: 更新结果
        """
        try:
            # 获取商家信息
            merchant = MerchantInfo.objects.get(merchant_id=user_id)

            # 更新商家信息
            if shop_name:
                merchant.shop_name = shop_name
            if location:
                merchant.location = location
            if business_hours:
                merchant.business_hours = business_hours
            if contact_info:
                merchant.contact_info = contact_info
            if introduction is not None:  # 注意：允许空字符串 ""
                merchant.introduction = introduction

            # 验证数据有效性
            merchant.full_clean()  # Django 自动校验字段约束
            merchant.save()

            return make_response(
                        code=200,
                        message="商家信息更新成功",
                        data={
                            "merchant_id": str(merchant.merchant_id),
                            "shop_name": merchant.shop_name,
                            "location": merchant.location,
                            "introduction": merchant.introduction
                        }
                    )

        except MerchantInfo.DoesNotExist:
            raise ValidationError("商家信息不存在")
        except Exception as e:
            raise ValidationError(f"更新失败：{str(e)}")

    @staticmethod
    def get_merchant_info(merchant_id):
        """
        获取指定商家的完整信息（含基本信息和所有图片）
        :param merchant_id: 商家的 UUID
        :return: 统一格式响应
        """
        try:
            merchant = MerchantInfo.objects.get(merchant_id=merchant_id)
        except MerchantInfo.DoesNotExist:
            return make_response(code=404, message="商家不存在")

        # 获取所有关联图片（按排序顺序），并转换为 Base64
        images = []
        merchant_images = MerchantImage.objects.filter(merchant=merchant).select_related('image').order_by('sort_order')

        for mi in merchant_images:
            image = mi.image
            try:
                # 将 BinaryField 数据转为 Base64 字符串
                base64_data = base64.b64encode(image.image_data).decode('utf-8')
            except Exception as e:
                # 可选：记录日志或跳过损坏图片
                continue

            images.append({
                "data": base64_data,
                "mime_type": image.mime_type,
                "is_cover": mi.is_cover,
                "sort_order": mi.sort_order
            })

        return make_response(
            code=200,
            message="成功",
            data={
                "merchant_id": str(merchant.merchant_id),
                "shop_name": merchant.shop_name,
                "location": merchant.location,
                "contact_info": merchant.contact_info,
                "business_hours": merchant.business_hours,
                "introduction": merchant.introduction,
                "register_time": merchant.register_time.isoformat() if merchant.register_time else None,
                "images": images
            }
        )

    @staticmethod
    def list_all_merchants():
        """
        获取所有商家及其封面图、分类数量、订单数、评分等简要信息
        :return: 统一格式响应
        """
        merchants = MerchantInfo.objects.prefetch_related('merchant_images__image').all().order_by('-register_time')

        if not merchants.exists():
            return make_response(code=200, message="暂无商家", data=[])

        result = []
        for merchant in merchants:
            # 获取封面图：优先使用 is_cover=True 的图片，否则取排序第一张
            cover_image = merchant.merchant_images.filter(is_cover=True).first()

            if not cover_image and merchant.merchant_images.exists():
                # 按 sort_order 排序后取第一张
                cover_image = merchant.merchant_images.order_by('sort_order').first()

            image_info = None
            if cover_image:
                image = cover_image.image
                image_info = {
                    "data": image.image_data.hex(),  # BinaryField 转 hex 字符串
                    "mime_type": image.mime_type
                }

            # 获取分类数量
            category_count = merchant.categories.count()

            # 获取最近订单数量（示例：过去30天）
            recent_orders = merchant.orders.filter(
                create_time__gte=timezone.now() - timezone.timedelta(days=30)
            ).count()

            # 获取平均评分
            avg_rating = merchant.orders.filter(rating__gt=0).aggregate(
                models.Avg('rating')
            )['rating__avg']

            result.append({
                "merchant_id": str(merchant.merchant_id),
                "shop_name": merchant.shop_name,
                "location": merchant.location,
                "contact_info": merchant.contact_info,
                "business_hours": merchant.business_hours,
                "introduction": merchant.introduction,
                "category_count": category_count,
                "recent_order_count": recent_orders,
                "avg_rating": float(avg_rating) if avg_rating else None,
                "cover_image": image_info
            })

        return make_response(
            code=200,
            message="获取成功",
            data=result
        )

